import {useCallback, useEffect, useRef, useState} from 'react';
import {saveMeltGrad, savePcrAllCycle} from "../pages/main/protocol/store/actionCreators";
import {MELT} from "../pages/main/protocol/config";
import {useDispatch, useSelector} from "react-redux";
import {WELL_TYPE} from "../pages/main/store/constants";
import {saveEndPointSetting} from "../pages/main/analysis/components/endPoint/store/actionCreators";
import {DATA_ANALYSIS_METHOD} from "../pages/main/analysis/components/quantification/config";

/**
 *
 * 改变浏览器窗口时获取dom元素的宽度和高度
 *
 * @param defaultSize {Object} 初始化dom尺寸
 * @param domElement {Element}  目标dom元素
 * @returns {Object} 目标dom元素的宽度和高度
 */
export function useSize(domElement, defaultSize) {
  const [size, setSize] = useState(defaultSize);
  const getSize = () => ({
    height: domElement.current.clientHeight,
    width: domElement.current.clientWidth
  });
  const handleResize = () => {
    setSize(getSize());
  };
  useEffect(() => {
    window.addEventListener("resize", handleResize);  // 监听
    return () => window.removeEventListener("resize", handleResize);  // 销毁
  });
  return size;
}

/***
 *
 * 防抖函数
 *
 * @param fn  业务方法
 * @param delay 延迟时间
 * @param dep 依赖项数组
 * @returns {function(...[*]): void}  防抖函数
 */
/*https://blog.csdn.net/sinat_17775997/article/details/94453167?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167818509316782425156957%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167818509316782425156957&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-94453167-null-null.142^v73^pc_search_v2,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=useCallback&spm=1018.2226.3001.4187*/

//useMemo返回缓存的变量，useCallback返回缓存的函数
export function useDebounce(fn, delay, dep = []) {
  const {current} = useRef({fn, timer: null});
  useEffect(function () {
    current.fn = fn;
  }, [fn]);

  return useCallback(function f(...args) {
    if (current.timer) {
      clearTimeout(current.timer);
    }
    current.timer = setTimeout(() => {
      current.fn(...args);
    }, delay);
  }, dep);
}


export function useThrottle(fn, delay, dep = []) {
  const {current} = useRef({fn, timer: 0});
  console.log(current);
  useEffect(function () {
    current.fn = fn;
    console.log(fn);
  }, [fn]);//函数作为依赖时，使用useCallBack范围memoized版本的回调，依赖改变才会改变
  return useCallback(function (...args) {
    let now = Date.now();
    /*  if (!current.timer) { //timer不为null时
     current.timer = setTimeout(() => {
     current.timer = null;
     }, delay);
     }*/
    console.log(`now`, now);
    console.log(`now - current.timer`, now - current.timer);
    if (now - current.timer >= delay) {
      current.timer = now;
      current.fn(...args);
    }
  }, dep);
}

/***
 *
 * 根据pcr的循环数和melt的梯度设置图像的横坐标
 *
 * @returns {function(*): Number}
 */
export function useChangeCoordinate() {
  const dispatch = useDispatch();
  const {pcrAllCycle} = useSelector(state => ({
    pcrAllCycle: state.protocolReducer.pcrAllCycle
  }));
  return function (data) {
    const pcrDataOrigin = data.pcrDataOrigin;
    let allCycle = pcrAllCycle;
    for (let i = 0; i < data.wells.length; i++) {
      for (let j = 0; j < 6; j++) {
        let cycle = data.wells[i].lines[j].quantificationOrigin.length;
        if (cycle > 0) {
          allCycle = cycle;
          break;
        }
      }
    }
    dispatch(savePcrAllCycle(allCycle));
    // if (pcrDataOrigin["channel1"]?.length > 0) {
    //   for (let i = 1; i <= 6; i++) {
    //     if (pcrDataOrigin[`channel${i}`][0].length > 0) {
    //       allCycle = pcrDataOrigin[`channel${i}`][0].length;
    //       break;
    //     }
    //   }
    //   //  设置pcr的总循环数,用于画图时设置横坐标
    //   dispatch(savePcrAllCycle(allCycle));
    // } else {
    //   allCycle = data.protocol.stages.filter(item => item.state === AMPLIFICATION).reduce((preValue, currentElement) => {
    //     return preValue + currentElement.cycle;
    //   }, 0);z
    //   dispatch(savePcrAllCycle(allCycle));
    // }
    //  设置melt的梯度,用于画图时设置横坐标
    if (data.protocol.stages.some(item => item.state === MELT)) {
      let meltStep = data.protocol.stages.filter(item => item.state === MELT)[0];
      dispatch(saveMeltGrad({
        minX: meltStep.steps[0].temperature,
        maxX: meltStep.steps[1].temperature
      }));
    }
    return allCycle;
  };
}

/***
 *
 * 保存终点法信息
 *
 * @returns {function(*): void}
 */
export function useSaveEndPointSetting() {
  const dispatch = useDispatch();
  const {targetSelectedArr, dataAnalysisMethod, isCN} = useSelector(
    state => ({
      targetSelectedArr: state.quantificationReducer.targetSelectedArr, //  保存Target Setting中Opt被选中的target的name
      dataAnalysisMethod: state.quantificationReducer.dataAnalysisMethod,  //  分析的方法(3种)
      isCN: state.languageReducer.isCN
    }));
  const getCycle = useChangeCoordinate();
  return function (data) {
    let cycles = getCycle(data);
    let endPointSetting = [];
    data.targets.forEach(item => {  //  获取well中相同target中cq的最大值和最小值
      let min = Infinity, max = 0, sum = 0, all = 0;
      data.wells.forEach(it => {  //  遍历well计算lowest,highest
        if (it.targets.length === 0) {
          return;
        }
        let rfu;
        try {
          rfu = it.lines[item.channelIndex][DATA_ANALYSIS_METHOD[dataAnalysisMethod]][cycles - 1];
        } catch (e) {
          console.log(e);
        }
        min = Math.min(min, rfu);
        max = Math.max(max, rfu);
        if (it.type === WELL_TYPE.NTC) {
          sum += rfu;
          all++;
        }
      });
      let ave = sum / all, value;
      if (isNaN(ave)) { //  计算cutOff
        value = null;
      } else {
        value = ave + (max - min) * 0.1;
      }
      endPointSetting.push({
        uuid: item.uuid,
        opt: true,
        target: item.name,
        color: item.color,
        channel: item.channel,
        cycles: cycles,
        cycleStatus: 1,
        rfu: 10,
        rfuLowest: min,
        rfuHighest: max,
        ntcAve: isNaN(ave) ? "" : ave,
        cutOff: value || ""
      });
    });
    dispatch(saveEndPointSetting(endPointSetting));
  };
}